package com.sofwin.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sofwin.mapper.SResourceMapper;
import com.sofwin.mapper.SRoleMapper;
import com.sofwin.mapper.SRoleResourceMapper;
import com.sofwin.pojo.SResource;
import com.sofwin.pojo.SRole;
import com.sofwin.pojo.SRoleExample;
import com.sofwin.pojo.SRoleExample.Criteria;
import com.sofwin.pojo.SRoleResource;
import com.sofwin.pojo.SRoleResourceExample;
import com.sofwin.service.RoleService;
@Service("roleService")
public class RoleServiceImpl implements RoleService {

	@Autowired
	private SRoleMapper mapper;
	@Autowired
	private SRoleResourceMapper roleResourceMapper;
	@Autowired
	private SResourceMapper resourceMapper;
	@Override
	public List<SRole> listRoles() {
		return mapper.selectByExample(null);
	}
	@Override
	public PageInfo<SRole> selectByPage(SRole role, Integer pageNumber, Integer pageSize) {
		PageHelper.startPage(pageNumber, pageSize);
		SRoleExample example = new SRoleExample();
		Criteria criteria = example.createCriteria();
		if(role!=null && role.getRoleName()!=null && !"".equals(role.getRoleName())) {
			criteria.andRoleNameLike("%"+role.getRoleName()+"%");
		}
		example.setOrderByClause("id desc");
		List<SRole> roles = mapper.selectByExample(example);
		return new PageInfo<SRole>(roles);
	}
	@Override
	public Boolean savePermission(SRoleResource roleResource) {
		Boolean status = true;
		try {
		// 判断当前节点是否为父级节点
		boolean isParent = checkNodeIsParent(roleResource.getResourceId());
		if(isParent) {
			// 父级节点操作
			boolean hasNode = checkHasCurrentNode(roleResource);
			if(hasNode) {
				// 删除自身及子节点
				deleteParentAndChildren(roleResource);
			}else {
				// insert 插入自身及子节点
				insertParentAndChildren(roleResource);
			}
		}else {
			// 子级节点操作
			boolean hasNode = checkHasCurrentNode(roleResource);
			if(hasNode) {
				// 删除自身
				boolean isOnlyChild = checkIsOnlyChild(roleResource);
				if(isOnlyChild) {
					// 删除自身+父
					deleteChildAndParent(roleResource);
				}else {
					// 删除当前
					deleteChild(roleResource);
				}
			}else {
				// 插入自身
				// hasParentNode 判断是否已经存在该子节点的父节点
				boolean hasParentNode = hasParentNode(roleResource);
				if(!hasParentNode) {
					// 插入父节点
					SRoleResource parent = new SRoleResource();
					parent.setRoleId(roleResource.getRoleId());
					parent.setResourceId(getParentId(roleResource.getResourceId()));
					insertRoleResource(parent);
				}
				// 插入当前节点
				insertRoleResource(roleResource);
			}
		}
		}catch(Exception ex) {
			status = false;
		}
		return status;
	}
	private void insertRoleResource(SRoleResource parent) {
		roleResourceMapper.insertSelective(parent);
	}
	private void deleteChild(SRoleResource roleResource) {
		SRoleResourceExample example = new SRoleResourceExample();
		SRoleResourceExample.Criteria criteria = example.createCriteria();
		criteria.andResourceIdEqualTo(roleResource.getResourceId());
		criteria.andRoleIdEqualTo(roleResource.getRoleId());
		roleResourceMapper.deleteByExample(example );
	}
	private void deleteChildAndParent(SRoleResource roleResource) {
		deleteChild(roleResource);
		SRoleResource parent = new SRoleResource();
		parent.setRoleId(roleResource.getRoleId());
		parent.setResourceId(getParentId(roleResource.getResourceId()));
		deleteChild(parent);
	}
	/**
	 * 判断是否包含有父级资源
	 * @param roleResource
	 * @return
	 */
	private boolean hasParentNode(SRoleResource roleResource) {
		Integer parentId = getParentId(roleResource.getResourceId());
		SRoleResourceExample example = new SRoleResourceExample();
		SRoleResourceExample.Criteria criteria = example.createCriteria();
		criteria.andRoleIdEqualTo(roleResource.getRoleId());
		criteria.andResourceIdEqualTo(parentId);
		// select *  from s_role_resource where roleid=1 and resourceId=parentId
		List<SRoleResource> roleResouces = roleResourceMapper.selectByExample(example );
		if(roleResouces!=null && roleResouces.size()>0) {
			return true;
		}
		return false;
	}
	/**
	 * 获取当前节点的父级节点id
	 * @param resourceId
	 * @return
	 */
	private Integer getParentId(Integer resourceId) {
		SResource resource = resourceMapper.selectByPrimaryKey(resourceId);
		return resource.getParentId();
	}
	/**
	 * 检查当前s_role_resource表中该节点的父节点的子节点只有一个
	 * @param roleResource
	 * @return
	 */
	private boolean checkIsOnlyChild(SRoleResource roleResource) {
		// 父节点
		Integer parentId = getParentId(roleResource.getResourceId());
		SRoleResourceExample example = new SRoleResourceExample();
		SRoleResourceExample.Criteria criteria = example.createCriteria();
		criteria.andRoleIdEqualTo(roleResource.getRoleId());
		criteria.andResourceIdEqualTo(parentId);
		int count = roleResourceMapper.countByExample(example );
		if(count==1) {
			return true;
		}
		return false;
	}
	/**
	 * 在插入父节点时插入所有子节点
	 * @param roleResource 父节点
	 */
	private void insertParentAndChildren(SRoleResource roleResource) {
		roleResourceMapper.insertParentAndChild(roleResource);
	}
	/**
	 * 删除父及子几点
	 * @param roleResource
	 */
	private void deleteParentAndChildren(SRoleResource roleResource) {
		roleResourceMapper.deleteParentAndChild(roleResource);
	}
	/**
	 * 
	 * @param roleResource
	 * @return
	 */
	private boolean checkHasCurrentNode(SRoleResource roleResource) {
		SRoleResourceExample example = new SRoleResourceExample();
		SRoleResourceExample.Criteria criteria = example.createCriteria();
		criteria.andRoleIdEqualTo(roleResource.getRoleId());
		criteria.andResourceIdEqualTo(roleResource.getResourceId());
		List<SRoleResource> roleResources = roleResourceMapper.selectByExample(example );
		if(roleResources!=null && roleResources.size()>0) {
			return true;
		}
		return false;
	}
	private boolean checkNodeIsParent(Integer resourceId) {
		SResource resource = resourceMapper.selectByPrimaryKey(resourceId);
		if(resource.getParentId()==0) {
			return true;
		}
		return false;
	}
	@Override
	public List<String> selectPermissionByRoleId(Integer roleId) {
		return mapper.selectPermissionByRoleId(roleId);
	}

}
